package com.sky.service.admin.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.util.StringUtil;
import com.sky.constant.JwtClaimsConstant;
import com.sky.constant.MessageConstant;
import com.sky.constant.PasswordConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.EmployeeDTO;
import com.sky.dto.EmployeeLoginDTO;
import com.sky.dto.EmployeePageQueryDTO;
import com.sky.exception.*;
import com.sky.mapper.admin.EmployeeMapper;
import com.sky.pojo.Employee;
import com.sky.properties.JwtProperties;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.admin.EmployeeService;
import com.sky.utils.JwtUtil;
import com.sky.vo.EmployeeLoginVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 员工管理业务层实现类
 *
 * @Author: Zhy
 * @Date: 2025-01-14 13:47
 * @Version: 1.0
 */
@Service
@RequiredArgsConstructor
public class EmployeeServiceImpl implements EmployeeService {
	private final EmployeeMapper employeeMapper;
	private final JwtProperties jwtProperties;

	/**
	 * 员工登录
	 *
	 * @param: employeeLoginDTO
	 * @return:
	 */
	@Override
	public Result<EmployeeLoginVO> login(EmployeeLoginDTO employeeLoginDTO) {
		String username = employeeLoginDTO.getUsername();
		String password = employeeLoginDTO.getPassword();

		// 校验参数
		if (StringUtil.isEmpty(username) || StringUtil.isEmpty(password)) {
			throw new ParameterIsNullException("用户名或密码不能为空");
		}

		// 1、根据用户名查询数据库中的数据
		Employee employee = employeeMapper.getByUsername(username);

		// 2、处理各种异常情况（用户名不存在、密码不对、账号被锁定）
		if (employee == null) {
			// 账号不存在
			throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
		}

		// 密码比对
		// 使用 MD5 加密算法加密密码
		password = DigestUtils.md5DigestAsHex(password.getBytes());
		if (!password.equals(employee.getPassword())) {
			// 密码错误
			throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
		}

		// 在使用 equals 方法对比时，
		if (StatusConstant.DISABLE.equals(employee.getStatus())) {
			// 账号被锁定
			throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
		}

		// 登录成功后，生成 jwt 令牌
		Map<String, Object> claims = new HashMap<>();
		claims.put(JwtClaimsConstant.EMP_ID, employee.getId());

		String token = JwtUtil.createJWT(jwtProperties.getAdminSecretKey(), jwtProperties.getAdminTtl(), claims);

		EmployeeLoginVO employeeLoginVO = EmployeeLoginVO.builder()
			.id(employee.getId())
			.userName(employee.getUsername())
			.name(employee.getName())
			.token(token)
			.build();
		return Result.success(employeeLoginVO);
	}

	/**
	 * 新增员工
	 *
	 * @return:
	 * @param: employeeDTO 员工信息参数
	 */
	@Override
	public Result<String> addEmployee(EmployeeDTO employeeDTO) {
		// 1. 参数校验
		// 判断用户名是否存在
		Employee dbEmp = employeeMapper.getByUsername(employeeDTO.getUsername());
		if (dbEmp != null) {
			throw new EmployeeNameExistException("用户" + employeeDTO.getUsername() + "已存在");
		}

		// 2. 参数处理
		// 设置初始默认密码，并对密码加密
		String password = DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes());
		Employee employee = new Employee();
		// 拷贝接收到的参数中的属性，到员工实体类中
		BeanUtils.copyProperties(employeeDTO, employee);
		// 补全实体
		employee.setPassword(password);
		employee.setStatus(1);

		// 3. 保存员工信息
		employeeMapper.addEmployee(employee);

		return Result.success("添加员工成功");
	}

	/**
	 * 分页查询员工信息
	 *
	 * @return:
	 * @param: employeePageQueryDTO 分页查询参数
	 */
	@Override
	public PageResult selectPageQuery(EmployeePageQueryDTO employeePageQueryDTO) {
		// 开启分页查询
		PageHelper.startPage(employeePageQueryDTO.getPage(), employeePageQueryDTO.getPageSize());

		List<Employee> employees = employeeMapper.selectPageQuery(employeePageQueryDTO);
		// 转换成 Page 对象，因为 PageHelper 底层使用 Page 对象进行分页
		Page<Employee> p = (Page<Employee>) employees;

		return new PageResult(p.getTotal(), p.getResult());
	}

	/**
	 * 根据 id 查询员工信息
	 *
	 * @return:
	 * @param: id 员工id
	 */
	@Override
	public Employee getEmployeeById(Long id) {
		// 参数校验
		if (id == null) {
			throw new ParameterIsNullException("员工id不能为空");
		}

		Employee employee = employeeMapper.getEmployeeById(id);
		// 基于安全性的考虑
		employee.setPassword("******");
		return employee;
	}

	/**
	 * 更新员工账号状态
	 *
	 * @return:
	 * @param: status 账号状态
	 * @param: id 员工id
	 */
	@Override
	public void startOrStop(Integer status, Long id) {
		// 参数校验
		if (id == null) {
			throw new ParameterIsNullException("员工id不能为空");
		}

		// 封装用户信息
		Employee employee = Employee.builder()
			.id(id)
			.status(status)
			.build();

		employeeMapper.updateEmployee(employee);
	}

	/**
	 * 更新员工信息
	 *
	 * @return:
	 * @param: employeeDTO 员工信息
	 */
	@Override
	public void updateEmployee(EmployeeDTO employeeDTO) {
		Employee employee = new Employee();

		// 拷贝接收到的参数中的属性，到员工实体类中
		BeanUtils.copyProperties(employeeDTO, employee);

		employeeMapper.updateEmployee(employee);
	}
}
